package com.wxb.annotationlog.annotation;

import com.alibaba.fastjson.JSON;
import com.wxb.annotationlog.cache.AnnotaionLogCache;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * @Description 注解日志面向切面
 * @Author Major
 * @Date 2020/6/1 11:49
 */
@Aspect
@Component
public class AnnotationLogAspect {

    Logger logger = LoggerFactory.getLogger(AnnotationLogAspect.class);

    //AOP 注解切面点
    @Pointcut("@annotation(com.wxb.annotationlog.annotation.AnnotationLog)")
    public void logAspect() {
    }

    //方法返回后触发
    @AfterReturning(pointcut = "logAspect()", returning = "result")
    public void afterReturing(JoinPoint joinPoint, Object result) {
        annotationLogCache(joinPoint,result);
    }

    //方法异常抛出触发
    @AfterThrowing(pointcut = "logAspect()", throwing = "e")
    public void afterThrowing(JoinPoint joinPoint, RuntimeException e) {
        String result = "";
        try{
            StackTraceElement stackTraceElement = e.getStackTrace()[0];
            String value = stackTraceElement.getClassName() + "." + stackTraceElement.getMethodName() + ":" + stackTraceElement.getLineNumber();
            result = e.getClass().getName() + ": " + e.getMessage() + "," + value;
        }catch (Exception ex){
            ex.printStackTrace();
        }
        annotationLogCache(joinPoint,result);
    }

    private void annotationLogCache(JoinPoint joinPoint, Object result){
        try{
            // 获取执行方法的类的名称（包名加类名）
            String className = joinPoint.getTarget().getClass().getName();
            // 获取实例和方法
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            Method method = signature.getMethod();
            AnnotationLog annotationLog = method.getAnnotation(AnnotationLog.class);
            String explain = annotationLog.value();                             //方法说明
            String params = JSON.toJSONString(joinPoint.getArgs());             //请求参数
            String returnResult = JSON.toJSONString(result);                    //响应结果
            String classMethod = className + "." + method.getName();            //请求方法

            logger.info(">>>>>请求方法>>>>>" + classMethod);
            logger.info(">>>>>方法说明>>>>>" + explain);
            logger.info(">>>>>请求参数>>>>>" + params);
            logger.info(">>>>>响应结果>>>>>" + returnResult);

            AnnotaionLogCache.saveLogCache(classMethod,explain,params,returnResult);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

}
